package com.yanqu.road.dao.impl.player;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.grandchild.GrandChildData;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GrandChildDataDaoImpl extends TempDataObjectDao<GrandChildData> {
    public static String getGrandChildDataSql = "select * from `t_u_grand_child` where `userId`=? and title = 0";
    public Map<String, GrandChildData> getGrandChildData(long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<String, GrandChildData> dataMap = new ConcurrentHashMap<>();
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(getGrandChildDataSql);
            int i = 1;
            call.setLong(i++, userId);
            rs = call.executeQuery();
            while (rs.next()) {
                GrandChildData data = parse(rs);
                dataMap.put(data.getId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    public static String getGrandChildTopDataSql = "SELECT ta.* FROM t_u_grand_child as ta,(SELECT professionId,MAX(earnSpeed+0)mEarnspeed FROM " +
            "t_u_grand_child WHERE userId=? and professionId>0 GROUP BY professionId) as tb WHERE ta.userId=? AND ta.professionId=tb.professionId AND ta.earnSpeed=tb.mEarnspeed;";
    public Map<Integer, GrandChildData> getGrandChildProfessionTopMap(long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, GrandChildData> dataMap = new ConcurrentHashMap<>();
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(getGrandChildTopDataSql);
            call.setLong(1, userId);
            call.setLong(2, userId);
            rs = call.executeQuery();
            while (rs.next()) {
                GrandChildData data = parse(rs);
                dataMap.put(data.getProfessionId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    public static String getProfessionGrandChildDataSql = "select * from `t_u_grand_child` where `userId`=? and `professionId`=? ORDER BY `earnSpeed`+0 desc";
    public List<GrandChildData> getProfessionGrandChildList(long userId, int professionId) {
        ResultSet rs = null;
        CallableStatement call = null;
        List<GrandChildData> dataList = new ArrayList<>();
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(getProfessionGrandChildDataSql);
            call.setLong(1, userId);
            call.setInt(2, professionId);
            rs = call.executeQuery();
            while (rs.next()) {
                GrandChildData data = parse(rs);
                dataList.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return dataList;
    }

    public static String getSingleGrandChildDataSql = "select * from `t_u_grand_child` where `userId`=? and `id`=?";
    public GrandChildData getGrandChildData(long userId, String id) {
        ResultSet rs = null;
        CallableStatement call = null;
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(getSingleGrandChildDataSql);
            call.setLong(1, userId);
            call.setString(2, id);
            rs = call.executeQuery();
            while (rs.next()) {
                GrandChildData data = parse(rs);
                return data;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return null;
    }

    public static String updateGrandChildDataSql = "update `t_u_grand_child` set appearanceId=?,nickName=?,lv=?,occupation=?,baseQuality=?,flairList=?,baseFlairList = ?,talentList=?,optionalList=?,reTalentTimes=?,archaeus=?,archaeusLastRecoverTime=?,earnSpeed=?,patronsId=?,sex=?," +
            "maxLv=?,quality=?,beautyId=?,trainExp=? ,title=?,professionId=?,affinityPatronsId=?,hadExam=? where userId=? and id=?";
    @Override
    protected boolean updateData(GrandChildData grandChildData) {
        grandChildData.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getUserDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getAppearanceId()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getNickName()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getLv()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getOccupation()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getBaseQuality()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getFlairList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getBaseFlairList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getTalentList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getOptionalList())));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getReTalentTimes()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getArchaeus()));
        para.put(i++, new DbParameter(Types.BIGINT, grandChildData.getArchaeusLastRecoverTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getEarnSpeed().toString()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getPatronsId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getSex()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getMaxLv()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getQuality()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getBeautyId()));

        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getTrainExp()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getTitle()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getProfessionId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getAffinityPatronsId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getHadExam()));



        para.put(i++, new DbParameter(Types.BIGINT, grandChildData.getUserId()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getId()));
        if (getDb().executeNoneQuery(updateGrandChildDataSql, para) > 0) {
            return true;
        }
        return false;
    }

    public static String insertGrandChildDataSql = "insert into `t_u_grand_child`(userId,id,appearanceId,nickName,lv,occupation,baseQuality,flairList,baseFlairList,talentList,optionalList,reTalentTimes,archaeus,archaeusLastRecoverTime,earnSpeed,patronsId,sex,maxLv,quality,beautyId," +
            "trainExp,title,professionId,affinityPatronsId,hadExam) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    @Override
    protected boolean addData(GrandChildData grandChildData) {
        grandChildData.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getUserDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.BIGINT, grandChildData.getUserId()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getAppearanceId()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getNickName()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getLv()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getOccupation()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getBaseQuality()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getFlairList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getBaseFlairList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getTalentList())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(grandChildData.getOptionalList())));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getReTalentTimes()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getArchaeus()));
        para.put(i++, new DbParameter(Types.BIGINT, grandChildData.getArchaeusLastRecoverTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, grandChildData.getEarnSpeed().toString()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getPatronsId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getSex()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getMaxLv()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getQuality()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getBeautyId()));


        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getTrainExp()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getTitle()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getProfessionId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getAffinityPatronsId()));
        para.put(i++, new DbParameter(Types.INTEGER, grandChildData.getHadExam()));


        if (getDb().executeNoneQuery(insertGrandChildDataSql, para) > 0) {
            return true;
        }
        return false;

    }

    @Override
    protected GrandChildData parseData(ResultSet rs) throws SQLException {
        GrandChildData grandChildData = new GrandChildData();
        grandChildData.setUserId(rs.getLong("userId"));
        grandChildData.setId(rs.getString("id"));
        grandChildData.setAppearanceId(rs.getInt("appearanceId"));
        grandChildData.setNickName(rs.getString("nickName"));
        grandChildData.setLv(rs.getInt("lv"));
        grandChildData.setOccupation(rs.getInt("occupation"));
        grandChildData.setBaseQuality(rs.getInt("baseQuality"));
        if (!StringUtils.isNullOrEmpty(rs.getString("flairList"))) {
            grandChildData.setFlairList(JSON.parseObject(rs.getString("flairList"), new TypeReference<List<Integer>>() {}));
        }
        if (!StringUtils.isNullOrEmpty(rs.getString("baseFlairList"))) {
            grandChildData.setBaseFlairList(JSON.parseObject(rs.getString("baseFlairList"), new TypeReference<List<Integer>>() {}));
        }
        grandChildData.setTalentList(JSON.parseObject(rs.getString("talentList"), new TypeReference<java.util.List<java.lang.Integer>>() {}));
        grandChildData.setOptionalList(JSON.parseObject(rs.getString("optionalList"), new TypeReference<java.util.List<java.lang.Integer>>() {}));
        grandChildData.setReTalentTimes(rs.getInt("reTalentTimes"));
        grandChildData.setArchaeus(rs.getInt("archaeus"));
        grandChildData.setArchaeusLastRecoverTime(rs.getLong("archaeusLastRecoverTime"));
        grandChildData.setEarnSpeed(new BigInteger(rs.getString("earnSpeed")));
        grandChildData.setPatronsId(rs.getInt("patronsId"));
        grandChildData.setSex(rs.getInt("sex"));
        grandChildData.setMaxLv(rs.getInt("maxLv"));
        grandChildData.setQuality(rs.getInt("quality"));
        grandChildData.setBeautyId(rs.getInt("beautyId"));
        grandChildData.setTrainExp(rs.getInt("trainExp"));
        grandChildData.setTitle(rs.getInt("title"));
        grandChildData.setProfessionId(rs.getInt("professionId"));
        grandChildData.setAffinityPatronsId(rs.getInt("affinityPatronsId"));
        grandChildData.setHadExam(rs.getInt("hadExam"));

        return grandChildData;
    }

    public List<GrandChildData> getPatronsShowChild(long userId, int patronsId, int size) {
        ResultSet rs = null;
        CallableStatement call = null;
        List<GrandChildData> list = new ArrayList<>();
        String sql = "select * from `t_u_grand_child` where `userId`=? and patronsId = ? and title  > 0 order by title,earnSpeed+0 asc limit ?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setLong(i++, userId);
            call.setInt(i++, patronsId);
            call.setInt(i++, size);
            rs = call.executeQuery();
            while (rs.next()) {
                GrandChildData data = parse(rs);
                list.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return list;
    }
}
